#include "PosnLampModel.h"
#include "Common/DataStructureMacro.h"
#include "Common/Information.h"
#include "audio_service_api.h"
#include "ssas_api.h"
#define LOG_TAG "HMI"
#include "log_api.h"

#define PSON_ALARM_AUDIO_ID AUDIO_7

typedef enum 
{
    ALWAYS_OFF,
    ALWAYS_ON,
    EMERGENCY,
} MachineState;

static MachineState currentStatus;
static Option_U8    showFlag;
static uint8_t      widget_visible_mask = 0;

static void init()
{
    currentStatus = ALWAYS_OFF;
    showFlag.update_ = false;
    showFlag.value_ = 0;
}

static MachineState getNewState()
{
    MachineState newState = ALWAYS_OFF;
    int msgState = COM_MSG_INIT;
    Std_ReturnType comRet = E_NOT_OK;
    do
    {
        msgState = get_message_state(COM_IC_EXTERIOR_LIGHTING_HS);
        if(COM_MSG_INIT == msgState || COM_MSG_TIMEOUT == msgState)
        {
            newState = ALWAYS_OFF;
            break;
        }

        uint16_t headLamp = 0;
        comRet = Com_ReceiveSignal(COM_SID_TaPnLgtAtv, &headLamp);
        if(E_OK != comRet)
        {
            newState = ALWAYS_OFF;
            break;
        }

        uint16_t tailPsonLamp = 0;
        comRet = Com_ReceiveSignal(COM_SID_MaiLgtSw, &tailPsonLamp);
        if(E_OK != comRet)
        {
            newState = ALWAYS_OFF;
            break;
        }

        if(OFF == headLamp)
        {
            newState = ALWAYS_OFF;
            break;
        }

        //headLamp == ON
        if(0x00 == tailPsonLamp || 0x01 == tailPsonLamp)
        {
            newState = ALWAYS_OFF;
            break;
        }

        if(0x02 == tailPsonLamp || 0x03 == tailPsonLamp)
        {
            VehicleKeyState vehState = getVehileState();
            uint16_t doorOpen = isDriverDoorOpen();
            if(VEHILE_OFF == vehState && DOOR_OPEN == doorOpen)
            {
                newState = EMERGENCY;
            }
            else
            {
                newState = ALWAYS_ON;
            }
            break;
        }

    } while (false);
    

    return newState;
}

static void handlStateTransition(MachineState newStatus)
{
    if(newStatus != currentStatus)
    {
        switch (currentStatus)
        {
            case EMERGENCY:
                //close popup todo
                stop_sound_request(PSON_ALARM_AUDIO_ID);
                break;

            case ALWAYS_OFF:
            case ALWAYS_ON:
                //ignore
                break;
            
            default:
                LOG_E("leave:Airbag unknow state : %d\n", currentStatus);
                break;
        }

        currentStatus = newStatus;

        switch (currentStatus)
        {
            case EMERGENCY:
                //show popup
                
                play_sound_request(PSON_ALARM_AUDIO_ID, 500, 500, 90000);
                break;
            
            case ALWAYS_OFF:
            case ALWAYS_ON:
                //ignore
                break;

            default:
                LOG_E("entry:Airbag unknow state : %d\n", currentStatus);
                break;
        }
    }
}

static void postprocess()
{
    switch (currentStatus)
    {
        case EMERGENCY:
        {
            setOptionValue_U8(&showFlag, true);
            break;
        }

        case ALWAYS_ON:
        {
            setOptionValue_U8(&showFlag, true);
            break;
        }

        case ALWAYS_OFF:
        {
            setOptionValue_U8(&showFlag, false);
            break;
        }
        
        default:
            LOG_E("postprocess:Airbag unknow state : %d\n", currentStatus);
            break;
    }
}

static void run()
{
    MachineState newStatus = getNewState();
    handlStateTransition(newStatus);
    postprocess();
}


static void release()
{

}

PosnLampModel g_PosnLampModelInstance = {
    {
        init,
        run,
        release,
        MIN_PERIOD,
    },
};

// ----------------------------------View------------------------------
void refresh_tt18View(ItuElement* elememt, bool isUnconditional)
{
    if(showFlag.update_)
    {
        ituCheckBoxSetChecked((ITUCheckBox*)elememt->widget_, showFlag.value_);
        showFlag.update_ = false;
    }
}

void reporting_self_validity_tt18View(ItuElement* elememt)
{
    uint8_t is_visible = (elememt && elememt->isVaild_) ? 0x01 : 0x00;
    widget_visible_mask <<= 1;
    widget_visible_mask |= is_visible;
}